﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZX.EHR.Library;
using ZX.BLL.Extend;
using ZX.DBModule;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ZX.BLL;

namespace ZX.Text
{
    /// <summary>
    /// 薪资表达式解析类
    /// </summary>
    [TestClass]
    public class SalaryFormulaResolveTest
    {
        [TestMethod]
        public void GetValues()
        {
            //string tempformula = "<个人所得税>";
            //string tempStr = SalaryFormulaResolve.GetInitialExpression(tempformula, "98AEF802-1CB0-43D7-8FFE-0B1C1E34BE7D");
            //string abc = tempStr;



            BEmployeeSalary bll = new BEmployeeSalary();
            bll.CalProvisionSalaryData("2013-04");

            string empId = "9A6F97B1-445D-4F4B-8E81-2CB666543741";
            hrEmployee tempemployee = new hrEmployee();
            tempemployee.ID = new Guid(empId);
            tempemployee.DepartmentID = new Guid("F2641836-1472-44E4-8545-8937CA4738B4");
            tempemployee.PostID = new Guid("36498FA9-1D49-4F8F-846B-FBDCB3758CD8");
            SalaryFormulaResolveTemp.CalSingleEmployeeSalarySQL(empId, "2012-09");
            //变量定义
            //BaseBussnies<hrEmployee> empbll = new BaseBussnies<hrEmployee>(new hrEmployee());
            //计算所有员工薪资
            //int count = empbll.GetRowCount("EmployeeStatus=1");
            //empbll.PageIndex = 1;
            //empbll.PageSize = 20;
            //empbll.Order = "ID";
            //empbll.Desc = "Yes";
            //int currentCount = 0;
            //while (currentCount < count)
            //{
            //    IList<BaseEntity> empLists = empbll.GetEntitysSplitPage("EmployeeStatus=1");
            //    foreach (BaseEntity entityEmp in empLists)
            //    {
            //        hrEmployee emp = entityEmp as hrEmployee;
            //        SalaryFormulaResolve.CalcEmployeeSalary(emp, "2012-11");
            //    }
            //    currentCount += empbll.PageSize;
            //    empbll.PageIndex++;
            //}
        }

        //    /// <summary>
        //    /// 计算员工某个月份的工资
        //    /// </summary>
        //    /// <param name="emp">员工对象</param>
        //    /// <param name="yearMonth">年月</param>
        //    public void CalcEmployeeSalary(hrEmployee emp,string yearMonth)
        //    {
        //        salSalarySolution salarySolution = new salSalarySolution();
        //        BaseBussnies salarySoutionBll = new BaseBussnies(salarySolution);
        //        salDeptSolution deptSolution = new salDeptSolution();
        //        BaseBussnies deptSolutionBll = new BaseBussnies(deptSolution);
        //        salSalaryItem salaryItem = new salSalaryItem();
        //        BaseBussnies salaryItemBll = new BaseBussnies(salaryItem);
        //        IList<BaseEntity> listSalaryItems = null;
        //        BaseBussnies bll = new BaseBussnies();
        //        //根据员工ID获取薪资方案,计算其薪资
        //        //先判断是不否有个人薪资方案
        //        deptSolution = deptSolutionBll.GetEntityByCondition("DeptID='" + emp.ID.ToString() + "' and Flag=2") as salDeptSolution;
        //        if (deptSolution == null) //没有个人对应的薪资方案
        //        {
        //            //查找相应的岗位薪资方案
        //            //获取岗位
        //            DatPost post = new DatPost();
        //            BaseBussnies postBll = new BaseBussnies(post);
        //            post = postBll.GetEntityById(emp.PostID.ToString()) as DatPost;
        //            if (post != null)
        //            {
        //                deptSolution = deptSolutionBll.GetEntityByCondition("DeptID='" + post.PostID.ToString() + "' and Flag=1") as salDeptSolution;
        //            }
        //            if (deptSolution == null) //没有部门对应的薪资方案
        //            {
        //                //查找相应部门薪资方案
        //                //根据员工ID获取所在部门
        //                DatDepartment dept = new DatDepartment();
        //                BaseBussnies deptbll = new BaseBussnies(dept);
        //                dept = deptbll.GetEntityById(emp.DepartmentID.ToString()) as DatDepartment;
        //                //部门薪资方案
        //                if (dept != null)
        //                {
        //                    deptSolution = deptSolutionBll.GetEntityByCondition("DeptID='" + dept.DeptID.ToString() + "' and Flag=0") as salDeptSolution;
        //                }
        //            }
        //        }
        //        if (deptSolution == null) return;//没有为该员工配置薪资方案
        //        //获取薪资方案所有薪资项
        //        listSalaryItems = salaryItemBll.GetEntitysByCondition("SalarySolutionID='" + deptSolution.SolutionID.ToString() + "'");
        //        //计算各薪资项的值
        //        //先删除该员工该年月薪资数据
        //        bll.RunSqlCommand("delete from salEmployeeSalaryResult where EmployeeID='" + emp.ID.ToString() + "' and YearMonth='" + yearMonth + "'");
        //        //构建薪资插入或更新SQL语句
        //        string rsSql = "insert into salEmployeeSalaryResult(ID,SalarySultionID,EmployeeID,YearMonth,BeginDate,EndDate,CalDate";
        //        List<double> resultLists = new List<double>();
        //        if (listSalaryItems == null) return;
        //        foreach (BaseEntity entity in listSalaryItems)
        //        {
        //            salSalaryItem tempSalaryItem = entity as salSalaryItem;
        //            double rs = GetItemDataValue(tempSalaryItem.DataSource, emp.ID.ToString(), deptSolution.SolutionID.ToString(), yearMonth);//计算结果
        //            rsSql += "," + tempSalaryItem.ItemName;
        //            resultLists.Add(rs);//保存到结果列表中
        //        }
        //        DateTime date = DateTime.Parse(yearMonth);
        //        string startDate = date.ToString("yyyy-MM-dd");
        //        date = date.AddMonths(1);
        //        date = date.AddDays(-1);
        //        string endDate = date.ToString("yyyy-MM-dd");
        //        rsSql += ") values(newid(),'" + deptSolution.SolutionID.ToString() + "','" + emp.ID.ToString() + "','" + yearMonth + "','" + startDate + "','" + endDate + "','" + DateTime.Now.ToString("yyyy-MM-dd") + "'";
        //        foreach (double d in resultLists)
        //        {
        //            rsSql += "," + d;
        //        }
        //        rsSql += ")";
        //        //将数据插入结果表
        //        bll.RunSqlCommand(rsSql);
        //    }

        //    /// <summary>
        //    /// 解析薪资表达式
        //    /// 表达式中可能出现的几类涉及计算数据的字符串:
        //    /// 1.[表名.列名],将其替换成相应的数据即可
        //    /// 2.函数,根据函数表将其替换
        //    /// </summary>
        //    /// <param name="formula">表达式</param>
        //    /// <param name="empId">员工ID</param>
        //    /// <param name="salarySolutionId">薪资解决方案ID</param>
        //    /// <returns></returns>
        //    private double GetItemDataValue(string formula, string empId,string salarySolutionId,string yearMonth)
        //    {
        //        string exp = GetExpression(formula, empId, salarySolutionId,yearMonth);
        //        Expression expression = new Expression(exp);
        //        double rs = expression.Compute(0);
        //        return rs;
        //    }

        //    private string GetExpression(string formula, string empId, string salarySolutionId,string yearMonth)
        //    {
        //        string rsstr = formula;
        //        //替换表字段的表达式为值
        //        while (rsstr.Contains("["))
        //        {
        //            //先找出[表.字段]
        //            int startIndex = rsstr.IndexOf("[");
        //            int endIndex = rsstr.IndexOf("]");
        //            string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
        //            //将[表.字段]替换成数值
        //            string temp = replacedStr.Substring(1, replacedStr.Length - 2);//取出表.字段
        //            string[] token = temp.Split('.');//token[0]-表名,token[1]-列名
        //            //在salSalaryRelationTable表中根据表名找到tableName
        //            salSalaryRelationTable salaryRelationTable = new salSalaryRelationTable();
        //            BaseBussnies tempbll = new BaseBussnies(salaryRelationTable);
        //            salaryRelationTable = tempbll.GetEntityByCondition("Name='" + token[0] + "'") as salSalaryRelationTable;
        //            string tableName = salaryRelationTable.TableName;//tableName
        //            //获取字段名
        //            salSalaryRelationFields salaryRationField = new salSalaryRelationFields();
        //            BaseBussnies salaryFieldBll = new BaseBussnies(salaryRationField);
        //            salaryRationField = salaryFieldBll.GetEntityByCondition("salRelationTableID='" + salaryRelationTable.ID + "' and FieldDes='" + token[1] + "'") as salSalaryRelationFields;
        //            string sql = "select " + salaryRationField.FieldName + " from " + tableName + " where EmployeeID='" + empId + "'";
        //            //包含年月字段
        //            if (salaryRelationTable.YearMonthField.Trim() != string.Empty)
        //            {
        //                sql += " and " + salaryRelationTable.YearMonthField.Trim() + "='" + yearMonth + "'";
        //            }
        //            BaseBussnies bll = new BaseBussnies();
        //            System.Data.DataTable dt = bll.GetDataBySqlComm(sql);
        //            string newStr = dt.Rows.Count == 0 ? "0" : dt.Rows[0][0].ToString();
        //            rsstr = rsstr.Replace(replacedStr, newStr);//替换成数值表达式
        //        }
        //        //替换函数为表达式
        //        while (rsstr.Contains("<"))
        //        {
        //            //先找出<函数>
        //            int startIndex = rsstr.IndexOf("<");
        //            int endIndex = rsstr.IndexOf(">");
        //            //函数名
        //            string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
        //            string funName = replacedStr.Substring(1, replacedStr.Length - 2);
        //            //获取函数表达式
        //            salSalaryFunction salaryFun = new salSalaryFunction();
        //            BaseBussnies salaryFunBll = new BaseBussnies(salaryFun);
        //            salaryFun = salaryFunBll.GetEntityByCondition("Name='" + funName + "'") as salSalaryFunction;
        //            string returnStr = "0";
        //            if (salaryFun != null) //薪资函数存在,不存在该函数则为0
        //            {
        //                //函数返回表达式
        //                salSalaryFunctionParameter salaryParam = new salSalaryFunctionParameter();
        //                BaseBussnies salaryParamBll = new BaseBussnies(salaryParam);
        //                returnStr = salaryFun.rsReturn;
        //                if (returnStr == "")
        //                {
        //                    //对有没有返回表达式的函数,考虑将其在后台实现函数功能
        //                    //通过反射获取函数,并执行函数
        //                    //先找出<参数>
        //                    IList<BaseEntity> listFunParams = salaryParamBll.GetEntitysByCondition("SalaryFunctionID='" + salaryFun.ID.ToString() + "'");
        //                    //目前只支持一个参数
        //                    salaryParam = listFunParams[0] as salSalaryFunctionParameter;
        //                    //获取参数值
        //                    double paramValue = GetItemDataValue(salaryParam.DataValue, empId, salarySolutionId, yearMonth);
        //                    //调用函数
        //                    if (salaryFun.Functions.Trim() == string.Empty)
        //                    {
        //                        returnStr = "0";
        //                    }
        //                    else
        //                    {
        //                        Type type = typeof(ZX.EHR.Web.fnSalary);
        //                        object[] parmArray = new object[] { paramValue };
        //                        MethodInfo mothodInfo = type.GetMethod(salaryFun.Functions, BindingFlags.Public | BindingFlags.Static);
        //                        returnStr = mothodInfo == null ? "0" : mothodInfo.Invoke(null, parmArray).ToString();
        //                    }
        //                }
        //                else
        //                {
        //                    //把函数中的参数替换为值
        //                    while (returnStr.Contains("<"))
        //                    {
        //                        //先找出<参数>
        //                        int index1 = returnStr.IndexOf("<");
        //                        int index2 = returnStr.IndexOf(">");
        //                        string replacedParamStr = returnStr.Substring(index1, index2 - index1 + 1);
        //                        //参数名
        //                        string paramName = replacedParamStr.Substring(1, replacedParamStr.Length - 2);
        //                        //获取参数值
        //                        salaryParam = salaryParamBll.GetEntityByCondition("Parameter='" + paramName + "' and SalaryFunctionID='" + salaryFun.ID.ToString() + "'") as salSalaryFunctionParameter;
        //                        returnStr = returnStr.Replace(replacedParamStr, salaryParam.DataValue);
        //                    }
        //                }
        //            }
        //            rsstr = rsstr.Replace(replacedStr, "(" + returnStr + ")");
        //            //递归替换表达式
        //            rsstr = GetExpression(rsstr,empId,salarySolutionId,yearMonth);
        //        }
        //        //替换薪资项为表达式
        //        while (rsstr.Contains("{"))
        //        {
        //            //先找出{薪资项}
        //            int startIndex = rsstr.IndexOf("{");
        //            int endIndex = rsstr.IndexOf("}");
        //            //要替换的
        //            string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
        //            //薪资项目说明
        //            string salaryItemNote = replacedStr.Substring(1, replacedStr.Length - 2);
        //            //获取薪资项表达式
        //            salSalaryItem salaryItem = new salSalaryItem();
        //            BaseBussnies salaryItemBll = new BaseBussnies(salaryItem);
        //            salaryItem = salaryItemBll.GetEntityByCondition("ItemNotes='" + salaryItemNote + "' and SalarySolutionID='" + salarySolutionId + "'") as salSalaryItem;
        //            if (salaryItem == null) //该薪资方案中不存在该薪资项
        //            {
        //                rsstr = rsstr.Replace(replacedStr, "0");
        //            }
        //            else
        //            {
        //                rsstr = rsstr.Replace(replacedStr, "(" + salaryItem.DataSource + ")");
        //            }
        //            //递归替换表达式
        //            rsstr = GetExpression(rsstr, empId, salarySolutionId,yearMonth);
        //        }
        //        return rsstr;
        //    }
        //}


        ///// <summary>    
        ///// 处理表达试运算---动态生成数学表达式并计算其值    
        ///// 表达式使用 C# 语法，可带一个的自变量(x)。    
        ///// 表达式的自变量和值均为(double)类型。    
        ///// </summary>    
        ///// <example>    
        ///// <code>    
        ///// Expression expression = new Expression("Math.Sin(x)");     
        ///// Console.WriteLine(expression.Compute(Math.PI / 2));     
        ///// expression = new Expression("double u = Math.PI - x;" +     
        ///// "double pi2 = Math.PI * Math.PI;" +     
        ///// "return 3 * x * x + Math.Log(u * u) / pi2 / pi2 + 1;");     
        ///// Console.WriteLine(expression.Compute(0));     
        /////     
        ///// Expression expression = new Expression("return 10*(5+5)/10;");    
        ///// Response.Write(expression.Compute(0));    
        ///// Response.End();    
        ///// </code>    
        ///// </example>    
        //class Expression
        //{
        //    object instance;
        //    MethodInfo method;
        //    /// <summary>        
        //    /// 表达试运算        
        //    /// </summary>        
        //    /// <param name="expression">表达试</param>        
        //    public Expression(string expression)
        //    {
        //        if (expression.IndexOf("return") < 0)
        //            expression = "return " + expression + ";";
        //        string className = "Expression";
        //        string methodName = "Compute";
        //        CompilerParameters p = new CompilerParameters();
        //        p.GenerateInMemory = true;
        //        CompilerResults cr = new CSharpCodeProvider().CompileAssemblyFromSource(p, string.Format("using System;sealed class {0}{{public double {1}(double x){{{2}}}}}", className, methodName, expression));
        //        if (cr.Errors.Count > 0)
        //        {
        //            string msg = "Expression(\"" + expression + "\"): /n";
        //            foreach (CompilerError err in cr.Errors)
        //                msg += err.ToString() + "/n";
        //            throw new Exception(msg);
        //        }
        //        instance = cr.CompiledAssembly.CreateInstance(className);
        //        method = instance.GetType().GetMethod(methodName);
        //    }
        //    /// <summary>        
        //    /// 处理数据        
        //    /// </summary>        
        //    /// <param name="x"></param>        
        //    /// <returns>返回计算值</returns>        
        //    public double Compute(double x)
        //    {
        //        return (double)method.Invoke(instance, new object[] { x });
        //    }
    }
}